{"_id":"@stapel/categories-react","_rev":"47-aa4a4b0004295bbb01963dd511f9c36c","name":"@stapel/categories-react","dist-tags":{"latest":"0.35.0"},"versions":{"0.1.0":{"name":"@stapel/categories-react","version":"0.1.0","license":"MIT","_id":"@stapel/categories-react@0.1.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"homepage":"https://github.com/usestapel/stapel-react#readme","bugs":{"url":"https://github.com/usestapel/stapel-react/issues"},"dist":{"shasum":"0b57f99366468ae66f06b6e081a61c19a9083f89","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.1.0.tgz","fileCount":205,"integrity":"sha512-E85jGsFsS98BN6PbO0zV7rIItF6bRiiA+tuj9JjiyLehYSBGNybebbq/eJc1VzJnIYI+xeZJx9eeebrDsO8LYg==","signatures":[{"sig":"MEQCIGMIkOZNe/CHupgA0qpASSxR409/lZZm+NRVDoOdfIG1AiANCnUfohn/BU1zEaN7TCmNTuSS7dh6qXBzLa2Ckm0I6Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":777210},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"gitHead":"bb9379f5de356cfd3e3a588561e9b8e632bf5640","scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"},"repository":{"url":"git+https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"_npmVersion":"10.9.2","description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"workspace:^","@types/react":"^19.1.0","@stapel/tokens":"workspace:^","@stapel/showcase":"workspace:^","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"workspace:^","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"workspace:^","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.15.0 <1.0.0","@stapel/tokens-antd":">=0.5.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.1.0_1787404002344_0.9702272133609464","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@stapel/categories-react","version":"0.2.0","license":"MIT","_id":"@stapel/categories-react@0.2.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"92a7fabddc952738c6a171bb56db3026b0936714","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.2.0.tgz","fileCount":206,"integrity":"sha512-xlgww/Q9KspzfVnwVl+gq3lMFAGtxgRcuLph+apkUqboCmNeojyOgzt7U9AJ6or8vClwsviCtDOtCUVEp2eBNQ==","signatures":[{"sig":"MEUCIQD7JJDIel3xs/IceO/zGekfL6U/xDFjiCMsR8Fwm/wcXwIgOiVPy+XgCY7A5h/rVwXIvV4o2I6g0t6g9BtnAExmmhk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":781435},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.15.0","@types/react":"^19.1.0","@stapel/tokens":"^0.5.0","@stapel/showcase":"^0.2.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.5.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.2.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.15.0 <1.0.0","@stapel/tokens-antd":">=0.5.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.2.0_1787442658411_0.041325173641379775","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@stapel/categories-react","version":"0.3.0","license":"MIT","_id":"@stapel/categories-react@0.3.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"50152cfc4bce7dc2707f964bfa2f854b86e98b18","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.3.0.tgz","fileCount":211,"integrity":"sha512-qL69/kZeU+lbI6te0oZsRj8G7dkDV98UoqAfRHk+MDQw14A6urqi/hUhsdxUZq9Po6ZDu6H020coMF1DQ3wh+w==","signatures":[{"sig":"MEUCIQDstOaK3hLxtmMGBTz664s0KJqF4epPWGSjefi31mWKWgIgJG0xESWRShU4960Q+fJ90yIoLYUWIQsmzRbFmpaxN5g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":797240},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.16.0","@types/react":"^19.1.0","@stapel/tokens":"^0.5.0","@stapel/showcase":"^0.2.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.5.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.2.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.15.0 <1.0.0","@stapel/tokens-antd":">=0.5.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.3.0_1787472217664_0.19768020648990814","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@stapel/categories-react","version":"0.3.1","license":"MIT","_id":"@stapel/categories-react@0.3.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"1ef22aebdd9f526e339e7215bbab54f8ccb651ff","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.3.1.tgz","fileCount":211,"integrity":"sha512-lomhqYW1MQMVMGS3DIpCSsRsJ/Hiqu7JnaAW5/Cdhsj82o92/MdFeS6lF8WOvJule+BXtozoMMtXzk124zpTSQ==","signatures":[{"sig":"MEUCIQD4E4dfglfFz+uNVdZCow8Ycm8TcREOfVXQNAGbIadgMAIgTx0/zvqTfdNsmSLWZCihHe73W/nvKpJjhIPgkjW0hC8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":797774},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.17.0","@types/react":"^19.1.0","@stapel/tokens":"^0.5.0","@stapel/showcase":"^0.2.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.5.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.2.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.16.0 <1.0.0","@stapel/tokens-antd":">=0.5.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.3.1_1787506499916_0.9503156938464488","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@stapel/categories-react","version":"0.5.0","license":"MIT","_id":"@stapel/categories-react@0.5.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"cb10d3a1eaa77081f79fa09e56f53757ae2c0215","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.5.0.tgz","fileCount":201,"integrity":"sha512-gl3JmXdEoMqUoeGhPx/5SDiZ9iTyBymPS1tnSDnMne63xOBns0Rf0xeiw1pNz369kE8V2JbdPRgCjxCQZyXEoQ==","signatures":[{"sig":"MEUCIFS/4VAUzodOFoFI5nSPBg5/20CMRgXgyrYnpoZc4jtLAiEAyNQvNvvEHW0JyVzR/kWninegDApL3WzfFQcQxh7bUz4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":856777},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.18.1","@types/react":"^19.1.0","@stapel/tokens":"^0.5.1","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.7.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.3.1","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.7.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.5.0_1787777937551_0.5217251335974449","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@stapel/categories-react","version":"0.5.1","license":"MIT","_id":"@stapel/categories-react@0.5.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"addc629e13676b2917f5e8117dce2f3f7fa69fe1","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.5.1.tgz","fileCount":201,"integrity":"sha512-t0xc9LMFzHEwLMcI4z2KG4iwpfe+U0oKYG5LC0g90C104Cvg52nzSGxYJH6Kjx8kMvoxAuxfSAN7H70tCpk+vg==","signatures":[{"sig":"MEYCIQDLWgpFypcXiMbJuR29xkCy5QaVxnfjTfzxBJElw8JClQIhAMScoe6+i/Y480hvMilvECZMQc5MBji7wiL1I/+77loh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.5.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":877655},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.20.0","@types/react":"^19.1.0","@stapel/tokens":"^0.6.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.8.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.4.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.7.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.5.1_1788124089921_0.6571651017291467","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@stapel/categories-react","version":"0.6.0","license":"MIT","_id":"@stapel/categories-react@0.6.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"8383872f04bf163c17209d1020bdd1b3671994c9","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.6.0.tgz","fileCount":211,"integrity":"sha512-BScbNi3lDLpbGWNjTO0Ef+km5228QmMQQK6vpa7M/1FMsLGXd63+QoIaecqryOuRImsqaW9jMa5c2KbV4Ltk6A==","signatures":[{"sig":"MEUCIBG8PiwgHQaDKutz6e3715hM7HQ9/E6nuD8ChVZiJtB3AiEA6tzxj4jHH2i2mdVTqZ6jBPESqrZbG8Smu+dwN8Ti/nM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":943096},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.20.0","@types/react":"^19.1.0","@stapel/tokens":"^0.6.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.9.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.5.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.7.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.6.0_1788139068249_0.46327802101337534","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@stapel/categories-react","version":"0.7.0","license":"MIT","_id":"@stapel/categories-react@0.7.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"9d8135e2674401fd333c517a7661b6118d5ed2a1","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.7.0.tgz","fileCount":236,"integrity":"sha512-itjRtX87C5e/uV2WKEaz2nYFg1/SCbo+lFxZ89e3LlkvCBeN8I/OmzD+ChdZhPbrGc0mW0pZAVn+YT/kf/jcHw==","signatures":[{"sig":"MEUCIG3+BiyWLuuuqogwzegUbU59fK83Fh0ZYS7pInaRclrKAiEA2IXm/iAxA1zvyb20EtsHtqUfJrK2Ndyac2uZKcdBQ8o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1073122},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.22.0","@types/react":"^19.1.0","@stapel/tokens":"^0.6.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.11.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.6.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.7.0_1788169982569_0.5174213177573783","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@stapel/categories-react","version":"0.8.0","license":"MIT","_id":"@stapel/categories-react@0.8.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"37aa795791373873374e8af292577b7d05b0914a","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.8.0.tgz","fileCount":251,"integrity":"sha512-eefB78eQ2waW6EkWr/xY7OrN7vvYM+LZFYc8gI9E3pIr4jcLip47qGZm91jxXeMgMN1pzVVJMbrPINlSIGlGvw==","signatures":[{"sig":"MEYCIQDDJOFFmuG1y4XNnt1QPi0DtUJcgh6c4RB18gA4zcYbuwIhALoQg6xVO2nDn+2PO6b9JHlcvlBXBK25IM+GSwe1HiJR","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1170538},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.22.0","@types/react":"^19.1.0","@stapel/tokens":"^0.6.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.11.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.8.1","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.8.0_1788291850133_0.3431639181585415","host":"s3://npm-registry-packages-npm-production"}},"0.9.1":{"name":"@stapel/categories-react","version":"0.9.1","license":"MIT","_id":"@stapel/categories-react@0.9.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"389bd9baca5d6a96b3705dbf84975eded320e733","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.9.1.tgz","fileCount":251,"integrity":"sha512-poE78K56md/jMJ0d8vfVnf74+q2DBDv+qu12woHdLfdoIzmZ+E9S887SZ02eav5ZnR4FOqeMQVO17/iZpfrIHg==","signatures":[{"sig":"MEUCIF816TsfzsypkhT7kNf3ySluDe9N9jZb2hBPHnaHzAVqAiEA76xXiAYaeDKTaKMmGahIHdCbT89M6bz028YZgUKvQyE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.9.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1250114},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.22.0","@types/react":"^19.1.0","@stapel/tokens":"^0.6.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.11.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.8.1","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.9.1_1788298360994_0.6347266069029753","host":"s3://npm-registry-packages-npm-production"}},"0.10.0":{"name":"@stapel/categories-react","version":"0.10.0","license":"MIT","_id":"@stapel/categories-react@0.10.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"d18538f96277dd48d1c4b2c10a1db070c724773a","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.10.0.tgz","fileCount":251,"integrity":"sha512-3EaXdZidcToLQA4geNJhz/HrOIRvQvqo4ZYwJI88Hmmw+TMx/ABe2e/onao5SzrOQ3S/7V+YjD4WYQ3g3foWDA==","signatures":[{"sig":"MEUCIQCTjfmLQQ+pjgj0FFTFyIIe5V8AqnOkJJ4YeWkJZbceCQIgal+9nYkXAusYhNN9AbzWUkc9q08QNTOZO9sw6tPGuog=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.10.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1266663},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.23.0","@types/react":"^19.1.0","@stapel/tokens":"^0.6.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.12.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.10.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.10.0_1788328739406_0.29157449995878904","host":"s3://npm-registry-packages-npm-production"}},"0.10.1":{"name":"@stapel/categories-react","version":"0.10.1","license":"MIT","_id":"@stapel/categories-react@0.10.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"7704928e49179b00267ed9ff8c9f62c46f4d35d5","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.10.1.tgz","fileCount":251,"integrity":"sha512-FJiyi/7zH5KE8/w8aG1wkDy5DiaXyDjzQej2gy2uOT7oMJVfpfgJtXK9I45ODIFYCDPsLpGcBrapvZdmHI4Bpw==","signatures":[{"sig":"MEUCIQCpaAvw1MFqTRC8NLiPewOu1zGASQhuYp8N+kwAlZpr6gIgEeGWdnPpd+Iax/2Nj8IhliLwDqvOXDm9qFPKkVjfFsU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.10.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1269325},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle","path":"dist/default/index.js","limit":"13 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.23.0","@types/react":"^19.1.0","@stapel/tokens":"^0.6.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.13.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.11.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.10.1_1788340884824_0.052749331976970515","host":"s3://npm-registry-packages-npm-production"}},"0.12.0":{"name":"@stapel/categories-react","version":"0.12.0","license":"MIT","_id":"@stapel/categories-react@0.12.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"20ffbc2a709653628149b703533f3c6b7b5afa9c","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.12.0.tgz","fileCount":256,"integrity":"sha512-C1sN+vpdFvLC7HCSyPUGeoVgOjR8ear4kkw7X69v7XSfU58yB0dtpR+1XYuW5n3KofbLiuOOmXrbcMzhT6hu1A==","signatures":[{"sig":"MEYCIQD6Bg95a9kfV/k9bFyKjw+V/4FRV7zrQrLbVsOwAOZQ6AIhANdZqREHjN4KA8JQHmdOhqN/25TWJ7TEUqsG9SjwRL2p","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.12.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1316306},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently.","path":"dist/default/index.js","limit":"13.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.23.1","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.14.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.11.1","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.12.0_1788364616477_0.14744832488816262","host":"s3://npm-registry-packages-npm-production"}},"0.12.1":{"name":"@stapel/categories-react","version":"0.12.1","license":"MIT","_id":"@stapel/categories-react@0.12.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"2dc5c64a9fa93fd3184da09da024b8a49999c627","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.12.1.tgz","fileCount":256,"integrity":"sha512-w/S8PBPLXGBwrdhNS4oDHBCRFY1W4sEqWOic/NNTdBlykMzCG9CTwleVJPlWvfQC15Egv0mXICbERrscTNYBWg==","signatures":[{"sig":"MEQCIHNPnPfc7XZh1NtKcxCy7spQaSa3lv13v6MoF5htCJlGAiA5+4u2V/cN5OD38kkc6QMP2f25kNqMvkZzaw//nABOxA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.12.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1320218},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently.","path":"dist/default/index.js","limit":"13.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.23.1","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.16.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.13.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.12.1_1788396815830_0.7708476923491654","host":"s3://npm-registry-packages-npm-production"}},"0.13.0":{"name":"@stapel/categories-react","version":"0.13.0","license":"MIT","_id":"@stapel/categories-react@0.13.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"5a4b0f1346f4c7067eaa048c3454d38de35cc59e","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.13.0.tgz","fileCount":256,"integrity":"sha512-EVU2kKTlvUwt1DtVwJz1+UOyeYJiDnOipgP6Ms0sT/QTo/dX8w8b8/36FbUbW3ZkQ+5GXvKccdX2y0M4xbHAcQ==","signatures":[{"sig":"MEYCIQCNbhu7iiDhI/0CNoFjDe8XHRAsdEqnDg1BUfmMmv+gCQIhALXHgf/20mTM2F7auOZ3A9lav2qRONyXWKIv/RljrB6s","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.13.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1323024},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently.","path":"dist/default/index.js","limit":"13.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.23.1","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.16.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.14.1","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.13.0_1788407688121_0.7282093382757495","host":"s3://npm-registry-packages-npm-production"}},"0.14.0":{"name":"@stapel/categories-react","version":"0.14.0","license":"MIT","_id":"@stapel/categories-react@0.14.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"79cb57473c510d433ddb3d65d5d31cab094c95d8","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.14.0.tgz","fileCount":256,"integrity":"sha512-NZdDI9wW6EJ/sEIVm38sEuNwSgbTLNbJcsvscQQHqf5cw66zEQo8UGy54lzEv3xsztYi3OgLkd9/ivtvgbBUGw==","signatures":[{"sig":"MEUCIQCVzp71xqG4UJf2Tm91lC4X31ywu2jMsdgtgju/2ekhlwIgQBZid5r+cVVar49z/dFUmpYwSIOO3US4dizjJuwTMoM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.14.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1327727},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd","path":"dist/index.js","limit":"9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently.","path":"dist/default/index.js","limit":"13.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.23.1","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.16.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.14.1","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.14.0_1788409554449_0.01788647346979566","host":"s3://npm-registry-packages-npm-production"}},"0.15.0":{"name":"@stapel/categories-react","version":"0.15.0","license":"MIT","_id":"@stapel/categories-react@0.15.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"9d51433557d5f6bd9b6de224c74b5b83c35ab383","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.15.0.tgz","fileCount":266,"integrity":"sha512-XFY9ZAry3pwfb9UBMCsHNkeQ/A00erOiHbdWd2fU6MSsFQ4TaDolgXKzxsaL4+aZamUtoBlZcCGWvhZ/NDxsNA==","signatures":[{"sig":"MEUCID5Wzed6BVhSqDK5+98JWxtiRLOQ/K+yvcSHMugQEQ0NAiEA5XnFt2iTBaU+a6xIIj52hDRPse7/ywrb97ekiT6E4JI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.15.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1438778},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently.","path":"dist/index.js","limit":"9.5 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry.","path":"dist/default/index.js","limit":"15.25 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.24.0","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.16.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.14.1","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.15.0_1788503692631_0.5900933893947737","host":"s3://npm-registry-packages-npm-production"}},"0.16.0":{"name":"@stapel/categories-react","version":"0.16.0","license":"MIT","_id":"@stapel/categories-react@0.16.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"350f822bb44befe9001e6ab036918d57619921db","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.16.0.tgz","fileCount":266,"integrity":"sha512-oPhWowLAqyNmH6kxU0R/g/837aiJZGbglk+7rbp2XSwdDuRY0T488S8lCh82EhkyCdmh8UO9wpxjfnFuN1ag3w==","signatures":[{"sig":"MEYCIQCnu/B23hF009J8Yj0/MA+Qo4C55AKo8XVmWKjBvRnatgIhAKY+/mi+1BO+wOiB3pQVmgZ7MfkeeC08w/w0JkwqLIEe","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.16.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1474219},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently.","path":"dist/index.js","limit":"9.5 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to.","path":"dist/default/index.js","limit":"15.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.0","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.16.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.15.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.16.0_1788507332251_0.17631423979902072","host":"s3://npm-registry-packages-npm-production"}},"0.17.0":{"name":"@stapel/categories-react","version":"0.17.0","license":"MIT","_id":"@stapel/categories-react@0.17.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"18b7d47e2facc5a55ccd9b099abc2481abec003c","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.17.0.tgz","fileCount":266,"integrity":"sha512-gron0SK9/UOKX2u8SltotoXpCs648CPKMU6xSgM9AO7IU/ZYWDVViq53RIyaik/docEgmaRzJpwnUOdGNME9IA==","signatures":[{"sig":"MEUCIB5poFxJQkRFUYf/6PfyXUknYy34Xriu2aCmQnobwlu4AiEAyPIHBgG6DibYsfDcnLpVH8n5Mi45jfiFE9fvDBXJBIg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.17.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1498502},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently.","path":"dist/index.js","limit":"9.5 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to.","path":"dist/default/index.js","limit":"15.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.0","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.16.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.15.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.17.0_1788516747149_0.8970302964073908","host":"s3://npm-registry-packages-npm-production"}},"0.18.0":{"name":"@stapel/categories-react","version":"0.18.0","license":"MIT","_id":"@stapel/categories-react@0.18.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"fe3012ea6a4559f937eeb2a9c67dcbeb6ab95e4d","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.18.0.tgz","fileCount":271,"integrity":"sha512-tEDYQOcbRTV+lyVAZvPARBUheX7rNJXSvsNGi12kOmiJfrMhKfbd8B6/c2sWi7jSWq3qWtYzndIh184RYNqpDA==","signatures":[{"sig":"MEUCIQDLCGU1dp8GWXWFPexS23AQxY/wni5iGCRXKt+eA6iWGwIgCW+bejahCzDAFlXarBG1Pk6MZfC07osz/xd8gFiyZss=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.18.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1553931},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need.","path":"dist/index.js","limit":"9.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back.","path":"dist/default/index.js","limit":"15.75 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.1","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.17.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.18.0_1788523269072_0.6637862824714751","host":"s3://npm-registry-packages-npm-production"}},"0.19.0":{"name":"@stapel/categories-react","version":"0.19.0","license":"MIT","_id":"@stapel/categories-react@0.19.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"b9807ec50246d70b2b6f41092092a1b97e087db9","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.19.0.tgz","fileCount":276,"integrity":"sha512-B5iQ58VVsnSh8drxENZ/OBiIfxW1/qY6Je03F8IiYqCcTn1L3EhcNQa7RauyV/3gxn4ko+WCknsNcQr5Eu95xA==","signatures":[{"sig":"MEUCIQDrdXJImSOfzPi07OOR2yf8hIpdkoU7sQmjIFQkjrR16QIgLhzQUQYikExucVOC/nK9jKeN2qdcUopNPWCk8KSRYig=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.19.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1590301},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain.","path":"dist/index.js","limit":"9.9 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on.","path":"dist/default/index.js","limit":"16 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.1","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.17.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.19.0_1788530848301_0.22201555915948257","host":"s3://npm-registry-packages-npm-production"}},"0.20.0":{"name":"@stapel/categories-react","version":"0.20.0","license":"MIT","_id":"@stapel/categories-react@0.20.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"804865c76a2badfa088d47701dd98500ecb2497b","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.20.0.tgz","fileCount":276,"integrity":"sha512-woBVnJEJYglW8ViXsa+F1zRx8TCaPYFbHgg/nu8vYirLsh51L8plcpv9JJCF/tZBRrSmPrEletsauFV8GY9KQg==","signatures":[{"sig":"MEQCIHW/kTRS4aZRWPk0N5UuxPvzMz7Tv7InEOsoFA4JVQc1AiBhMgEa2piiqhvRjVfSwsNL1htkZuz3tRrNHdDHY5U0SQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.20.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1606418},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch.","path":"dist/index.js","limit":"9.95 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand.","path":"dist/default/index.js","limit":"16.1 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.1","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.17.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.20.0_1788540213722_0.16156471803002326","host":"s3://npm-registry-packages-npm-production"}},"0.22.0":{"name":"@stapel/categories-react","version":"0.22.0","license":"MIT","_id":"@stapel/categories-react@0.22.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"d1df9274ef125b4872f8052f59a34aad4e52c582","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.22.0.tgz","fileCount":281,"integrity":"sha512-WSYobMTQg5LU1uo7ZUEVtbc4vWA6dwRAPOka+JL9DhgOAoU56dSNlAefCbQ6zvPop3u2jfacl19EEPjNT1DJQg==","signatures":[{"sig":"MEYCIQDw44X73txoX1NRfMWZ29XLqe4SGwMi+bafxkxDZXSJgwIhAOsC6bNLGNNfMjDHxcAz+WdzDRJvFRmZ/r7rcCVBNLN1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.22.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1706449},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper.","path":"dist/index.js","limit":"10.45 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line.","path":"dist/default/index.js","limit":"17.4 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.1","@types/react":"^19.1.0","@stapel/tokens":"^0.7.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.17.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.22.0_1788561992489_0.44473098345384754","host":"s3://npm-registry-packages-npm-production"}},"0.22.1":{"name":"@stapel/categories-react","version":"0.22.1","license":"MIT","_id":"@stapel/categories-react@0.22.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"01c79ac271ebfb2f9a57459e11f3b36e68585091","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.22.1.tgz","fileCount":281,"integrity":"sha512-RP0Cw6t1HjmCGaj4qNl6vPFbf6MTuBM7Gq/7jrolmMvIGl8pKgdqpwgWsrFGkUBYzBO7p+i3HVQOVlqBFgR/sw==","signatures":[{"sig":"MEUCIQCopisBe1NTkQczM/Iel1XTl3hrxV+QkeJzht8zf/LbdgIgGSQvi46q5mz0kI5qLgWc0YpgM0FacG6uc+TIE00BcxU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.22.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1711075},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper.","path":"dist/index.js","limit":"10.45 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand.","path":"dist/default/index.js","limit":"17.6 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.2","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.17.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.1","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.22.1_1788618056749_0.9600133096978691","host":"s3://npm-registry-packages-npm-production"}},"0.22.2":{"name":"@stapel/categories-react","version":"0.22.2","license":"MIT","_id":"@stapel/categories-react@0.22.2","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"cbae1742c40ce5fa848ea033985202a0716db8aa","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.22.2.tgz","fileCount":281,"integrity":"sha512-q5xuH72QUZUdsE1zOL0bGWcQPLT4IV+p+HNCYjRRe/Msvjv1qA8MNr8yBMOMOc3t1WcrNl0JoGpDJiW5G3aF9g==","signatures":[{"sig":"MEUCIQD7Q88m4DRbpsTtNb5jkZG+Z2p3YU+hfUqa4AkZ26tr6QIgYnz6UGwGgk1nta4T8sMS3gBS9HaMYFyKgy4rBCk6tgo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.22.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1723130},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper.","path":"dist/index.js","limit":"10.45 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand.","path":"dist/default/index.js","limit":"17.6 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.4","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.17.3","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.2","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.22.2_1788646204246_0.3659142712059944","host":"s3://npm-registry-packages-npm-production"}},"0.22.3":{"name":"@stapel/categories-react","version":"0.22.3","license":"MIT","_id":"@stapel/categories-react@0.22.3","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"a34a131edc1877cd5a1e579847062748b3b210c9","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.22.3.tgz","fileCount":281,"integrity":"sha512-f8mn053q7+Wp9XESa+XLTaN0Vrwc8rcy6iLwqOGouvHG4ZA9RVvjTen+lQ0h/h0BvUl3+MsmwBrtbYnm3MkeTw==","signatures":[{"sig":"MEYCIQDWy1LqpxUTm+5Ov/Z3U+ph6i+JMOqjrw3/+iB8M/N1HgIhALRFZkoWGnSmJC9UELdrq+eyzmSY8oS0JoLT7EgECvqA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.22.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1726702},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper.","path":"dist/index.js","limit":"10.45 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte.","path":"dist/default/index.js","limit":"17.8 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.4","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.17.3","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.4","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.22.3_1788659945821_0.5727434120035237","host":"s3://npm-registry-packages-npm-production"}},"0.23.0":{"name":"@stapel/categories-react","version":"0.23.0","license":"MIT","_id":"@stapel/categories-react@0.23.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"32be8050214ccfbd52783c6cc4f9b27a5f607acd","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.23.0.tgz","fileCount":281,"integrity":"sha512-dQ53k1YT2Lb3k+sRZeV5nB02Wub6qH10daV6FyhXxfMwzGk/jFhJVxORHIYDR3x9A7sl8fEy4HK9dbBXm0P1aw==","signatures":[{"sig":"MEQCIGRtkA1Sz3Sto6e3dnnCh+6Bz1nTjDDe7PM8FEoNZOfJAiAb8dO6+3KHPL17lWllCJ72p54dWNOWHpnLok7gVRkLyQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.23.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1740409},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper.","path":"dist/index.js","limit":"10.45 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has.","path":"dist/default/index.js","limit":"17.8 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.25.4","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.17.3","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.5","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.18.1 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.23.0_1788692454602_0.8848732733394618","host":"s3://npm-registry-packages-npm-production"}},"0.24.0":{"name":"@stapel/categories-react","version":"0.24.0","license":"MIT","_id":"@stapel/categories-react@0.24.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"ac4a0ec6b9d63caa235de5c1b4347eefa325a26b","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.24.0.tgz","fileCount":281,"integrity":"sha512-Cze8M8PBetgIZ5qW88Sa7mpgXGyaCBOO+EbgOXVKXvSg0+1AoD8NnvMI1TUC+Duz+MpJ5vRWqnXaycVFgDydhA==","signatures":[{"sig":"MEQCIHDCB6AagMsmKZhdjGwGfV5Kl34S7769WURCyjyV24oGAiBklrylphlLOY3IRhDQBhuF+fD+VDbLEE4tXm46cpo8Dw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.24.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1757861},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS, untouched by this wave: measured 10437 B — the caption test id and the keepPrevious wiring are both in the SKIN entry, and the headless one carries neither. 13 B of room, stated so the next change knows it is spending the last of it.","path":"dist/index.js","limit":"10.45 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it.","path":"dist/default/index.js","limit":"17.8 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.0","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.5","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.24.0_1788704161667_0.19479057931975863","host":"s3://npm-registry-packages-npm-production"}},"0.24.1":{"name":"@stapel/categories-react","version":"0.24.1","license":"MIT","_id":"@stapel/categories-react@0.24.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"bf99a455014135eacab98eab9d769b51d5b88501","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.24.1.tgz","fileCount":281,"integrity":"sha512-Bw/thf8elSHDRKR6EHqemKTBTz1aw2ox/yntR7eVnOsHWXXJkHkbJdOAdgbMVW/oYEiIeRR2Ef+3GX+4hqBygA==","signatures":[{"sig":"MEUCIQDRrpPUnfK4pdxHrJVyyRbMTV7TY5rb5el62l0B9+gIrQIgMP99EEElyrusUr5YlzvoJkILUQORYRRFUoe/R+w1mC8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.24.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1769045},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it.","path":"dist/index.js","limit":"10.45 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged.","path":"dist/default/index.js","limit":"17.8 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.0","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.5","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.1.0"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.24.1_1788709654323_0.9743069294032525","host":"s3://npm-registry-packages-npm-production"}},"0.24.2":{"name":"@stapel/categories-react","version":"0.24.2","license":"MIT","_id":"@stapel/categories-react@0.24.2","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"aa8ec37f827fcfab9bffa275064d303be3b074e8","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.24.2.tgz","fileCount":281,"integrity":"sha512-+yMjYt0+/K3p+BQnbPsjYr7VSXkWBwDTHARqGG98xCC/uUrsWQFE72kzKTbA1AhGf9Ff+5+EwxuhuxKVNtS5BA==","signatures":[{"sig":"MEUCIQCiVu5a+8RsYrkvrqNvd9z3Pwuk8LECJ5F/fMHrriJ7NQIgDZ6Nf/LWKJaFLIJFt5bv4mBR2dfLee8h8crF/KVfkhU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.24.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1794541},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag.","path":"dist/default/index.js","limit":"17.8 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.0","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.6","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.24.2_1788722979735_0.19102408229238077","host":"s3://npm-registry-packages-npm-production"}},"0.25.0":{"name":"@stapel/categories-react","version":"0.25.0","license":"MIT","_id":"@stapel/categories-react@0.25.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"69aab93f28d55ffe0c90191e8e264d0c055f0bc2","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.25.0.tgz","fileCount":281,"integrity":"sha512-/ylUljL3zL3EtL19bU+OfWhOXT4LCuFzLq00SQcZBgePUEs4Gos+/cc3kMO4o1iDMn6PkE2zbAwoXNxfCUcZKg==","signatures":[{"sig":"MEUCIEJBDqoAaCFje7C3tEB1kWTwRNA8sbhcLrSKcFTw8PMkAiEAwPjJHTeCdrFgwNvd2KJu7txhhh46/pSFs4mVSYb7O2o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.25.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1801244},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag.","path":"dist/default/index.js","limit":"17.8 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.0","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.16.6","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.25.0_1788858531936_0.696811323937564","host":"s3://npm-registry-packages-npm-production"}},"0.25.1":{"name":"@stapel/categories-react","version":"0.25.1","license":"MIT","_id":"@stapel/categories-react@0.25.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"8c0882c3c2bc175ea53b8e102975124d078c66f0","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.25.1.tgz","fileCount":281,"integrity":"sha512-8rzrDg3JCiZiQS4sWYrS+uY0fANBiKeILfZvNjQt85K6W9oTQNgTtY90i/5sNDvKEMLXKaFnKfn79EhZjuzLsg==","signatures":[{"sig":"MEUCIQCXVmN1eNylGVxwZT/kdAJcqViIWE19Opq1vZGEyYhY9QIgBZJKGlKps4aAUbVadLDaKW4liAxpOj8FRG1Illy4hZI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.25.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1802000},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag.","path":"dist/default/index.js","limit":"17.8 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.0","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.25.1_1788862352084_0.6811804751450146","host":"s3://npm-registry-packages-npm-production"}},"0.26.0":{"name":"@stapel/categories-react","version":"0.26.0","license":"MIT","_id":"@stapel/categories-react@0.26.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"81a232d83b82c397e7c72115fdbb747e305108b9","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.26.0.tgz","fileCount":281,"integrity":"sha512-wO25cx+f4wuzLeVjlZ9i+MRB1AaVqvxH7r19A2B3ETClgEKNQPAKxWaNO0/o2zXLQ4TZt5lhrcXH5cbfLS/TvA==","signatures":[{"sig":"MEYCIQDm8DwoKaJqXaZ3UeyruBWrXX4E+iLiwjK40aFEQbPYRQIhAPekELUAhNINwsPKpvISDuL63DXovlXJx2Tm0wyhfHqP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.26.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1905422},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing.","path":"dist/default/index.js","limit":"18.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.26.0_1789001590306_0.8446560464199406","host":"s3://npm-registry-packages-npm-production"}},"0.27.0":{"name":"@stapel/categories-react","version":"0.27.0","license":"MIT","_id":"@stapel/categories-react@0.27.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"e40f027630a8a3830ca57652e4f3183021f56324","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.27.0.tgz","fileCount":286,"integrity":"sha512-IiJvLPl3YmDrTdf03j0CkV52y4+lYtrcGks4Mv6RkiEoJAjSaTyc1DKmZ02gy12PPXJEQtYyRAvc+f2u4Oa4yw==","signatures":[{"sig":"MEUCIQC/bumjaDMwOUukucI2A+7OifwiBfFv/VpOqLN1fKdJRAIgAQ9u3M+ORZQOHTwNEb0gDsxCxJoNg9PUu1D5K0pdaRE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.27.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1940331},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing.","path":"dist/default/index.js","limit":"19 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.27.0_1789036407633_0.12932630996517025","host":"s3://npm-registry-packages-npm-production"}},"0.28.0":{"name":"@stapel/categories-react","version":"0.28.0","license":"MIT","_id":"@stapel/categories-react@0.28.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"4b7b3e990f982f0958ad00a5e8219eb1ba81fa28","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.28.0.tgz","fileCount":286,"integrity":"sha512-p9O1laFpYVc9v0eG4d6OdHAGoBnn8acLL69BC6lDN+gluhw95D4xIO7CVqYipQvSaL/tn0zaCa4CmjdTzSTfBw==","signatures":[{"sig":"MEYCIQCqOrSRX0J0gQ5raFdYKs5ipiHjUzeSirbcTLXjh2Zs2QIhAIhRHXTFvzscgTo+HAbg/gVhOQJcdbddmjQ2P5GuS9Kr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.28.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1958966},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has.","path":"dist/default/index.js","limit":"19 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.28.0_1789042951502_0.08348824583614656","host":"s3://npm-registry-packages-npm-production"}},"0.29.0":{"name":"@stapel/categories-react","version":"0.29.0","license":"MIT","_id":"@stapel/categories-react@0.29.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"8f52d5b02e9c913a64bacc82bf4aeaad9cc3e309","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.29.0.tgz","fileCount":286,"integrity":"sha512-1ow/azxHo+I4FhTeuV8qlwJDpLauac9xzQN43yDG5DBnjiOCNn7k56pHXp7WkVnbDPCItAxVLWHPzcDZQcEF9Q==","signatures":[{"sig":"MEYCIQCHgBU2G+6+Sl+bgsT/MjX6k/83f6vyEMCseK6YeoX2UwIhAK4BnZ9BQeEqQGffi6jqpbPUtDMJD/Izpj/qKmemIusd","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.29.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1968282},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched.","path":"dist/default/index.js","limit":"19 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.29.0_1789048678410_0.17704243141879772","host":"s3://npm-registry-packages-npm-production"}},"0.30.0":{"name":"@stapel/categories-react","version":"0.30.0","license":"MIT","_id":"@stapel/categories-react@0.30.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"97dcb0e38c4429788c41412b399d916207ca7cbc","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.30.0.tgz","fileCount":286,"integrity":"sha512-u7A2LdQ0ErbqfXQLhB7mJPQ1x4U3DeCmSG+fmTJ2iG0VBa8PGGMNgqQax6yzsR3AmNipATIme/27XtHVQZqLGg==","signatures":[{"sig":"MEUCIQCVELFi1/Yn5soWv+WAx8pBD4Lcc05dNFpOG/QaXbUkvgIgKfb0XIQsX1nril5i7oBs4WG3smHDx9VMIOLcLp53LiU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.30.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1985155},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B.","path":"dist/default/index.js","limit":"19.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.30.0_1789052343977_0.2794313366880272","host":"s3://npm-registry-packages-npm-production"}},"0.31.0":{"name":"@stapel/categories-react","version":"0.31.0","license":"MIT","_id":"@stapel/categories-react@0.31.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"8fdaaa20ba70a684b2dfef104d8beff710ae07d5","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.31.0.tgz","fileCount":286,"integrity":"sha512-SCveWL/GfhqNoghDxJRDTu5gPsLp3KEEl5QQIxqbZ2iM3wTgqfP552EwMUL1WVK4oHfeSMMCQRv6t/YkoiwMCA==","signatures":[{"sig":"MEUCIDNlokW9CViROG4laSHU/EL+6HMx6h6MG67XCiqoUq6cAiEAj6gXMIfF2HLj9uxo3nlLckT5A7uqYfz0UqvdAchy9Oo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.31.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1990819},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has.","path":"dist/default/index.js","limit":"19.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.31.0_1789090766331_0.8086501542341331","host":"s3://npm-registry-packages-npm-production"}},"0.31.1":{"name":"@stapel/categories-react","version":"0.31.1","license":"MIT","_id":"@stapel/categories-react@0.31.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"0e066798c4eff45d4c06def2649c37c3cff4a45d","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.31.1.tgz","fileCount":286,"integrity":"sha512-KH8skSsCxiuH3iWQGCoirqTlwFmz/9SOLOAVjEaz4hAXohu2l+UdEspiKyBhunEPkIEiV64cv/J56dlnV6RYgg==","signatures":[{"sig":"MEYCIQCbex36PtLeb9Ef8C6Ly2oBvzZ4UBxvNx2IeeJXKM6S3gIhAJERqgLpWmRbfRgE3XJZ5NFOMf/0u8AAWZGHE7/aUQM6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.31.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1996037},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has.","path":"dist/default/index.js","limit":"19.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.31.1_1789174505814_0.10414252369333554","host":"s3://npm-registry-packages-npm-production"}},"0.31.2":{"name":"@stapel/categories-react","version":"0.31.2","license":"MIT","_id":"@stapel/categories-react@0.31.2","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"cc5c6222e49292b815cad81c42d4fb72aceefc54","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.31.2.tgz","fileCount":286,"integrity":"sha512-JvibhQRMtkwmEwD8YFn6OEyQR2MXkl8v+0dO/VF4QU+b2oCL/KZwitvtwcKvFBbRkQ/DUy8F2Jfofv97jfY69Q==","signatures":[{"sig":"MEUCIHpbdq1u57xPp+SCkffr9bur7C21jrjwJbJrty/FUQslAiEAnxy/BgZuQbVDKwOdcSZU3O2vtPe3eSD2WxFzTV1o90Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.31.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2008112},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has.","path":"dist/default/index.js","limit":"19.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.31.2_1789272031535_0.3959149319575348","host":"s3://npm-registry-packages-npm-production"}},"0.31.3":{"name":"@stapel/categories-react","version":"0.31.3","license":"MIT","_id":"@stapel/categories-react@0.31.3","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"0e76dfcaeacb1d38ed2129a844e88ea3f530c31f","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.31.3.tgz","fileCount":286,"integrity":"sha512-rTLuSgzNBi+XMyTNUkNG5/5jX9ijmfj/9FDCgujqp7KRblzF9MhFTp7kM147ELU18nFl2shBpZhrcs8e6DBUHA==","signatures":[{"sig":"MEQCIFUhcPUcJmXPAGOmVyq+IEAt9xrXZmQ61EqaWlnIDCjCAiAyb5B5xj8VSMlACdezk9MFgdaYLjdT6CpNeI2HKpPUuA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.31.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2012928},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has.","path":"dist/default/index.js","limit":"19.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.31.3_1789276761045_0.7977098624749739","host":"s3://npm-registry-packages-npm-production"}},"0.31.4":{"name":"@stapel/categories-react","version":"0.31.4","license":"MIT","_id":"@stapel/categories-react@0.31.4","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"9a5f6dda5c0d389fb11875f97dcc0292d51f24a3","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.31.4.tgz","fileCount":286,"integrity":"sha512-MAkUs92Jjy99Rv8FOfkPXvq8xWhKt5EWI3t6OTHboACa/QpWgimF9+qegLw4TmK150BqSGWaLkZcCoKTRoaypg==","signatures":[{"sig":"MEQCIDUwCAD+pth6LKpctYX7VMgN0vVyMjEMpcreN4z3KK0NAiA9ZjCMFxctWzsowaBvjIH+HCjplpSe2N2OmpJygGpONg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.31.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2018437},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has.","path":"dist/default/index.js","limit":"19.5 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.18.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.31.4_1789300743085_0.795824945122966","host":"s3://npm-registry-packages-npm-production"}},"0.32.0":{"name":"@stapel/categories-react","version":"0.32.0","license":"MIT","_id":"@stapel/categories-react@0.32.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"248c4a2fd462e6406d4ef6e029a3fcfa2bf4dce1","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.32.0.tgz","fileCount":286,"integrity":"sha512-egq0oXt9sRnKif66KUFJfdLGDRl69pF59BM9Xg4ZCsSvw1/CB0nBAQhTR9/KH6LUwdXvUOyC0aHWzKAE5ZHiwA==","signatures":[{"sig":"MEUCIQCDREgMF1Qz+gOW3B6Ce7HvmWQDEd7io7ADDe4/+Rm4jwIgYwImUnPqWU0FfYdw4GrscJeWOhYHA5XET4KItoDftDg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.32.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2049496},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has. 19.5 -> 20 KB for the mega-menu becoming an OVERLAY in its own right (owner's desktop read of the stand, 2026-09-14). Measured with dependencies held constant, this package's src at HEAD before this wave and then at it: 19154 -> 19530 B — 376 B, and the line was already 187 B past the 18967 B this note last recorded (the card tile's tint and the trail's surface landed under it without a note), so the 346 B of room the last raise left had become 30 B of red. The 376 B is three things the panel now owns instead of the host: its own scroll box (`maxHeight`, `overflow-y: auto`, `overscroll-behavior: contain` — measured on the stand, the host's wrapper had nothing to scroll and the wheel chained 1500px into the page); the page lock while mounted (`lockPageScroll`, reference-counted, `scrollbar-gutter: stable` beside the hidden overflow, the same lock `SkinDialog` keeps private); and the rail row's fill leaving the style attribute for a hoisted sheet (`megaMenuCss`, the root class and its `-active` modifier) so `:hover` and `:focus-visible` can be said at all — plus `railWidth` and the trailing chevron. 20 KB leaves 470 B, the same order of room the 19 -> 19.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing.","path":"dist/default/index.js","limit":"20 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.0","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.22.0","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.32.0_1789411103808_0.18476157195837173","host":"s3://npm-registry-packages-npm-production"}},"0.33.0":{"name":"@stapel/categories-react","version":"0.33.0","license":"MIT","_id":"@stapel/categories-react@0.33.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"50833b3a41757267cc827bc07717bc7152f3ae99","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.33.0.tgz","fileCount":286,"integrity":"sha512-62hRT2yNg47+eIImRM+BOVUkM48uZCu/EqOMbRopRlmSm9CPGo76XXA/GH3Fi1aaa0sqVdfoZRSb/oUVuD+Sfg==","signatures":[{"sig":"MEUCIFUsa3J2/ze1TYAoIIC60A2arKiAXQ/t308mTDBjlVs1AiEAsFSgLThnyS6GVx34X4WEVQ5oCgvlDEoD4v2nRr0xlL4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.33.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2054264},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has. 19.5 -> 20 KB for the mega-menu becoming an OVERLAY in its own right (owner's desktop read of the stand, 2026-09-14). Measured with dependencies held constant, this package's src at HEAD before this wave and then at it: 19154 -> 19530 B — 376 B, and the line was already 187 B past the 18967 B this note last recorded (the card tile's tint and the trail's surface landed under it without a note), so the 346 B of room the last raise left had become 30 B of red. The 376 B is three things the panel now owns instead of the host: its own scroll box (`maxHeight`, `overflow-y: auto`, `overscroll-behavior: contain` — measured on the stand, the host's wrapper had nothing to scroll and the wheel chained 1500px into the page); the page lock while mounted (`lockPageScroll`, reference-counted, `scrollbar-gutter: stable` beside the hidden overflow, the same lock `SkinDialog` keeps private); and the rail row's fill leaving the style attribute for a hoisted sheet (`megaMenuCss`, the root class and its `-active` modifier) so `:hover` and `:focus-visible` can be said at all — plus `railWidth` and the trailing chevron. 20 KB leaves 470 B, the same order of room the 19 -> 19.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing.","path":"dist/default/index.js","limit":"20 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.1","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.22.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.33.0_1789517634696_0.6522693016059689","host":"s3://npm-registry-packages-npm-production"}},"0.33.1":{"name":"@stapel/categories-react","version":"0.33.1","license":"MIT","_id":"@stapel/categories-react@0.33.1","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"4f61b1c5c941d8041fdf088351d97d9b45382272","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.33.1.tgz","fileCount":286,"integrity":"sha512-55jCgwvAOqVl5mCIWUcKRa+E00m0c6G3jg0g1w0uNdWtqUyFpwojzD34pIcd0UC8mZB2WHv5kKL1ArfSM+UHBg==","signatures":[{"sig":"MEYCIQDII4pknxAsY4RC+7cTRjERh9hRCLZOWwJFDACGSd2ivgIhAMSh0bWjAX3sBbLSxhJIzjwtE4wVURwWRw3/QUDYHmF2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIF41mOhIABhqvpCv+OtDauchF6vvusv8r5qOfgNRP8bfAiEAni6SHuxlE+Q2R8MH5uV3LE8M6VXzedoR+qWyuPbzUEQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.33.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2056476},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has.","path":"dist/index.js","limit":"10.75 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has. 19.5 -> 20 KB for the mega-menu becoming an OVERLAY in its own right (owner's desktop read of the stand, 2026-09-14). Measured with dependencies held constant, this package's src at HEAD before this wave and then at it: 19154 -> 19530 B — 376 B, and the line was already 187 B past the 18967 B this note last recorded (the card tile's tint and the trail's surface landed under it without a note), so the 346 B of room the last raise left had become 30 B of red. The 376 B is three things the panel now owns instead of the host: its own scroll box (`maxHeight`, `overflow-y: auto`, `overscroll-behavior: contain` — measured on the stand, the host's wrapper had nothing to scroll and the wheel chained 1500px into the page); the page lock while mounted (`lockPageScroll`, reference-counted, `scrollbar-gutter: stable` beside the hidden overflow, the same lock `SkinDialog` keeps private); and the rail row's fill leaving the style attribute for a hoisted sheet (`megaMenuCss`, the root class and its `-active` modifier) so `:hover` and `:focus-visible` can be said at all — plus `railWidth` and the trailing chevron. 20 KB leaves 470 B, the same order of room the 19 -> 19.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing.","path":"dist/default/index.js","limit":"20 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.1","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.22.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.33.1_1789697376458_0.7101347560397782","host":"s3://npm-registry-packages-npm-production"}},"0.34.0":{"name":"@stapel/categories-react","version":"0.34.0","license":"MIT","_id":"@stapel/categories-react@0.34.0","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"dist":{"shasum":"0ce9f3e3de9bd1423e0683f3e5a1453ed0e60c7d","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.34.0.tgz","fileCount":286,"integrity":"sha512-A2/4ivlfoedG+rLMbu9EzYQoMKIjHBn8H/KqaYk46FVFZOBYZlPiUTe2SgCKkP4WlKe9bg2SSv2/Yuwq5T1Sog==","signatures":[{"sig":"MEUCIQCgNkmZeAxocBa4xTnAG0wEWls9J80ziqtHn7DE9UBxnwIgIN6Pd9cUtVt64F5dbZP1PfXBfzO11ulGQNyCORlMYq8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCICCL2nL3IfEbMc/44H+qdlvfDzE3Ar2pTJgjGrbeBeF3AiEAiYI4DLUwRs5VrlKEiVJkIVeM4gmH8/Me2r/WJfHhmqc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.34.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2061419},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has. 10.75 -> 11 KB for the UNION of a chips parent's children (stapel-categories 0.24.0): measured 10759 B, 72 B over the 10687 B this note last recorded, which is 9 B past the 10.75 KB line — raised here, in the train that carries the change, rather than left as a red somebody reruns. The 72 B is `partial` and `carriedBy` on `CategoryFeatureEntry` and their two normalizations, plus `carried_by` on `CategoryFeature`. The wire keys themselves are free, as the three kinds of child were: a type erases. What is not free is that the effective schema stopped being an intersection — a feature only SOME children carry is now IN a parent's list with the children that carry it named, so a host can label or filter by it instead of discovering the row is missing, and `visibleFeatures` has one more case it deliberately does NOT hide. 11 KB leaves 241 B, the same order of room the 10.45 -> 10.75 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing.","path":"dist/index.js","limit":"11 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has. 19.5 -> 20 KB for the mega-menu becoming an OVERLAY in its own right (owner's desktop read of the stand, 2026-09-14). Measured with dependencies held constant, this package's src at HEAD before this wave and then at it: 19154 -> 19530 B — 376 B, and the line was already 187 B past the 18967 B this note last recorded (the card tile's tint and the trail's surface landed under it without a note), so the 346 B of room the last raise left had become 30 B of red. The 376 B is three things the panel now owns instead of the host: its own scroll box (`maxHeight`, `overflow-y: auto`, `overscroll-behavior: contain` — measured on the stand, the host's wrapper had nothing to scroll and the wheel chained 1500px into the page); the page lock while mounted (`lockPageScroll`, reference-counted, `scrollbar-gutter: stable` beside the hidden overflow, the same lock `SkinDialog` keeps private); and the rail row's fill leaving the style attribute for a hoisted sheet (`megaMenuCss`, the root class and its `-active` modifier) so `:hover` and `:focus-visible` can be said at all — plus `railWidth` and the trailing chevron. 20 KB leaves 470 B, the same order of room the 19 -> 19.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing.","path":"dist/default/index.js","limit":"20 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.26.1","@types/react":"^19.1.0","@stapel/tokens":"^0.8.1","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.22.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.0","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/categories-react_0.34.0_1789711989381_0.5515094886676806","host":"s3://npm-registry-packages-npm-production"}},"0.35.0":{"_id":"@stapel/categories-react@0.35.0","dist":{"shasum":"7c700f74724606e7f5f5d4db1ed3a1ecec4e4024","tarball":"https://registry.npmjs.org/@stapel/categories-react/-/categories-react-0.35.0.tgz","fileCount":286,"integrity":"sha512-QLEy5Tzuoc+oLDzh1QGOKzy7j8HM+K8AoEmkDdZ/YEOKoWb6ABCOdzDlGdhQoZzPlhRj0OnilwH3KPE+Kh6z2w==","signatures":[{"sig":"MEUCIQCaT4FsAX6CbAG14wnYVRahci7CbhZC+OZ4KY6QtQTPtgIgIxQ5cB5iuT11BVT1kB9bcG/yZAaFRnTcSeSV8sqbVuY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDN0Od6tgqBwit/zMPwtMFrTR/Zjt2HAw0+Udt/lHCxFQIgZbHdP+v74f48bgDZc/Yz8qWTE+mkoIe0TaXq+ecvcnY="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@stapel%2fcategories-react@0.35.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2063817},"main":"./dist/index.js","name":"@stapel/categories-react","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./default":{"types":"./dist/default/index.d.ts","default":"./dist/default/index.js"},"./i18n/es":{"types":"./dist/i18n/es.d.ts","default":"./dist/i18n/es.js"},"./i18n/ru":{"types":"./dist/i18n/ru.d.ts","default":"./dist/i18n/ru.js"},"./llms.txt":"./llms.txt","./manifest":"./manifest.json","./package.json":"./package.json","./manifest.json":"./manifest.json","./nav-manifest.json":"./nav-manifest.json"},"license":"MIT","scripts":{"lint":"eslint .","size":"size-limit","test":"tsc -p tsconfig.test.json && vitest run --exclude test/prodBundlePurity.test.ts","build":"tsc -p tsconfig.json","test:pack":"vitest run test/prodBundlePurity.test.ts"},"version":"0.35.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8222ebaa-8033-4db6-b307-d158db98591b"}},"repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"size-limit":[{"name":"index — the headless pair (client + tree assembly + delta sync + hooks): no antd. 9 -> 9.5 KB for the browse-stage wave: the nested tree read (useCategoryTree + its key), browseStage, and categoryIconSrc. Three small pure additions the storefront needs on every catalogue page, 31 B over the old line - raised deliberately, not silently. 9.5 -> 9.75 KB for the effective-features wave: the `X-Effective-From` raw-fetch carve-out (`api/featuresRaw.ts`, the ONE legal home of `fetch` for a header `StapelClient.get` cannot see), `visibleFeatures`, and the cascade's `partitionChild` pass-through — 70 B over the old line, and every byte of it is either the one request `client.get` cannot make or a pure filter a composer and a facet rail both need. 9.75 -> 9.9 KB for the transparent-wrapper rule (`catalog/wrapper.ts`'s `isTransparentWrapper`/`browseChildren`, plus the cascade's own one-rung merge): a one-child import level the census found under a real root, skipped without a second copy of `hasChildren`'s fallback chain. 9.9 -> 9.95 KB for `isWrapperAncestor`: the same wrapper rule asked of a breadcrumb trail's own rows (`tn_children_pks`'s count standing in for the full sibling array a tile page has and a crumb list does not) — 20 B over the old line, no second fetch. 9.95 -> 10.4 KB for the AUTHORED `children_as: \"transparent\"` value (stapel-categories 0.20.4): `isTransparentNode`, the dev-only leaf guard, `browseChildren`'s per-child splice among several siblings (not only a lone wrapper), `browseStage`'s `parent` argument and `childControl`'s `\"none\"` case, plus the cascade's generalised multi-rung collapse — a second, independent way a level goes invisible, alongside the structural one this budget already carried. 10.4 -> 10.45 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): `categoryLiveChildCount`, `hasChildren`'s and `categoryChildIds`' new lead tier, `isWrapperAncestor`'s switch off raw `tn_children_pks` parsing, and the shared dev-warning helper for the fallback — 37 B over the old line, replacing a ghost-inflated column with the reader's own live answer everywhere it decided a leaf, a count or a wrapper. 10.45 KB HOLDS for the held trail (this wave): measured 10445 B, 8 B over the 10437 B this note last recorded. The headless trail takes a `keepPrevious` of its own — core's `useKeptLoad`, plus the branch that now builds ONE `state` for both addresses instead of returning twice — so a screen holding its frame no longer has a hole punched in it by the one surface that answered `loading` on its own. A budget is not raised for a change that fits under the line it already has, so the line stands; 5 B of room is what is left, and the next change to this entry spends it. 10.45 -> 10.75 KB for `axis_role` (stapel-categories 0.21.0), which is the change that spent them: `CategoryFeatureEntry` gains `axisRole` and `CategoryFeaturesBag` gains `axes`, both decided by `@stapel/attributes-react`'s `axisRoleOf`/`byAxisRole` rather than by a second copy of the closed vocabulary here. Measured with dependencies held constant, this package's src without the two readers and then with them: 10445 -> 10582 B. The 137 B is every storefront's own slug table (`brand` / `make` / `vendor` / `manufacturer`) deleted: a catalogue that spells the axis a fifth way used to drop out of the «more of this make» link with no error, and this entry is where the answer arrives. 10.75 KB HOLDS for the three kinds of child (stapel-categories 0.22.0, this wave): measured 10687 B against the 10.75 KB line, 105 B over the 10582 B this note last recorded, and 63 B of room left. The 105 B is `isLinkedChild`/`isVirtualChild`/`isRowChild`, `hasChildren`'s leading answer for a VALUE, `catalog/wrapper.ts`'s two refusals to collapse a POINTER, `categoryChildTileEntries` and the dev-only warning for a value nobody gave an address to. The wire union itself is free — a type erases — and so is a pointer's rendering path, because there is none: every key of a linked child is the target's, which is exactly what let `CategoryRowChild` be `Category` plus a flag instead of a second shape with a second mapping. A budget is not raised for a change that fits under the line it already has. 10.75 -> 11 KB for the UNION of a chips parent's children (stapel-categories 0.24.0): measured 10759 B, 72 B over the 10687 B this note last recorded, which is 9 B past the 10.75 KB line — raised here, in the train that carries the change, rather than left as a red somebody reruns. The 72 B is `partial` and `carriedBy` on `CategoryFeatureEntry` and their two normalizations, plus `carried_by` on `CategoryFeature`. The wire keys themselves are free, as the three kinds of child were: a type erases. What is not free is that the effective schema stopped being an intersection — a feature only SOME children carry is now IN a parent's list with the children that carry it named, so a host can label or filter by it instead of discovering the row is missing, and `visibleFeatures` has one more case it deliberately does NOT hide. 11 KB leaves 241 B, the same order of room the 10.45 -> 10.75 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing.","path":"dist/index.js","limit":"11 KB"},{"name":"default — the antd skin (catalog, category page, carousel, picker, breadcrumbs) must stay out of the main bundle. 13.25 -> 13.5 KB when the compact-tile anatomy landed (density prop, centred icon-over-label variant, its own measure hook): the skin crossed the old line by 3 bytes, and a budget that fails on 3 B of a shipped feature is a gate proving nothing - raised deliberately, not silently. 13.5 -> 15.25 KB when the desktop mega-menu landed: a root rail with a roving-tabindex menu model, a pane of second-level columns with a capped third level, the outside-click and Escape wiring and the minWidth guard - one panel, 1.44 KB, and no part of it is carried by a host that imports only the headless entry. 15.25 -> 15.5 KB for the storefront's three slots: the tile grid's wrapping layout (minTileWidth, the auto-fill track), its icon-address resolver, and the category page's heading slot - 19 B over the old line, and every byte of it is a host drawing its own copy of this skin that it no longer has to. 15.5 -> 15.75 KB for the mega-menu's onSelect (a rail root, a column header and a third-level link each report which node was pressed, with the `stapel/clickable-needs-event` opt-out beside them) and the category page's own `measure` prop — 70 B over the old line, replacing a host's `!important` override with a value it can read back. 15.75 -> 16 KB for the tiles arm's own wrapper skip (`TileSubcategories`, one small `useCategoryChildren` read gated on the single-child case) — the storefront's `/c/uslugi` no longer draws one tile for an import level nobody may act on. 16 -> 16.1 KB for a transparent wrapper's own breadcrumb crumb: `linked: false` renders it as plain text instead of a link, decided by `isWrapperAncestor` or a host `unlink` predicate — 81 B over the old line for a defect the storefront integrator named by hand. 16.1 -> 17.3 KB for the reference's second-level tile (owner's ruling 2026-09-04): `CategoryTileGrid`'s `size: \"compact\"` anatomy (a third tile shape, horizontal, half the root tile's height), and `maxVisible`/`overflow: \"modal\"` — the «All categories» overflow tile plus `AllCategoriesDialog`, a `SkinDialog`-backed searchable list of every child, wired through `CategoryPage`'s `subcategoryTileSize`/`subcategoryMaxVisible`/`subcategoryOverflow`. 17.3 -> 17.4 KB for `children_pks`/`children_count` (stapel-categories 0.20.5): the same live-child-count switch as the headless entry's budget, carried here because `CategoryPage`'s tile/wrapper decisions run through the same `catalog/stage.ts` and `catalog/wrapper.ts` — 94 B over the old line. 17.4 -> 17.6 KB for `<CategoryPage gutter={false}>`: a page mounted inside shell-react's own content box stops adding a second indent on top of the shell's, which is the whole of the one-page-gutter change on this side of the seam. Measured with dependencies held constant, this package's src at the commit before it and then at it: 17.35 -> 17.43 KB, 80 B for an opt-out that removes a double margin a host was otherwise cancelling by hand. 17.6 -> 17.8 KB for the two host-measured slots of this wave: `<CategoryPage headingLevel>`, `<CategoryTileGrid reserve>` (the loading arm's box, now one shared component, lent to a host-owned fetch) and the reserved row taking the SHAPE of the density it will draw rather than always 4/3 — 0.024 of layout shift on the storefront's home, paid by the arm that exists to prevent it. Measured with dependencies held constant across the wave: 17.43 -> 17.56 KB, and a ceiling with 40 B of room left is a gate that fails on the next honest byte. 17.8 KB HOLDS for `labelLines` (this wave): measured 17601 B against the 17.8 KB line, 45 B over the 17.56 KB this note last recorded. The grid's own prop costs nothing measurable — it is threaded through a `tileBody` that now builds its label element ONCE and places it, instead of writing the same span three times per anatomy, and the two moves cancel (17558 B at that point); the 45 B is `<CategoryPage subcategoryLabelLines>`, three rungs of conditional spread so the `\"tiles\"` arm reaches the same number as it reaches `size` and `maxVisible`. A budget is not raised for a change that fits under the line it already has. 17.8 KB HOLDS for keepPrevious and the named caption (this wave): measured 17614 B against the 17.8 KB line, 13 B over the 17601 B this note last recorded. `<CategoryPage keepPrevious>` is close to free because the composed frame REPLACED the four fields `useCategoryPageSource` used to hand back beside the state (`current`/`children`/`depth`/an `unknown` nobody read) — the landing now travels inside the LoadState, which is what lets the page hold a WHOLE previous frame instead of half of one, and the memory itself is core's `useKeptLoad`. The 13 B is `CATEGORY_TILE_LABEL_TESTID` and the `??` that falls back to it. 17.8 KB HOLDS for the held TRAIL (this wave): measured 17713 B against the 17.8 KB line, 99 B over the 17614 B this note last recorded. The breadcrumb bar is the one row that sits ABOVE the page's own `<LoadBoundary>`, so it was the one row a sibling press could still blank — `<CategoryPage>` now hands it the row the held FRAME names rather than the raw `categoryId`, and forwards `keepPrevious` to it; the 99 B is that derivation, the bar's own prop, and the conditional spread that keeps a bar mounted alone unchanged. 17.8 KB HOLDS for `axis_role` (this wave): measured 17725 B against the 17.8 KB line, 12 B over the 17713 B this note last recorded — the skin draws no axis badge and never will from this change, and the 12 B is the two extra fields travelling through `<CategoryFeatureList>`'s bag. 17.8 -> 18.5 KB for the «All» tile's art and the two new kinds of child. The line was ALREADY 143 B behind before this wave: `<CategoryTileGrid allTile>`'s own glyph and `labelHyphens` landed at 17943 B against an 17800 B ceiling, which is why the size job on main had a red waiting for it — raised here, in the train that carries those changesets, rather than left as a gate somebody reruns. The remaining 266 B (17943 -> 18209 B, measured with dependencies held constant) is a VALUE of an expanded branch getting drawn: `isVirtualTile` and the three places a tile differs by kind (its React key, whether the link carries a category identity, whether there is art to resolve) in both `TileRow` and `AllCategoriesDialog`, plus `<CategoryPage hrefForVirtual>` and the conditional spread that reaches the `\"tiles\"` arm with it. A POINTER costs nothing at all here and that is the point: it arrives as an ordinary entry and draws as one. 18.5 KB leaves 291 B — the same order of room the 17.6 -> 17.8 raise left, and deliberately not the 41 B an 18.25 KB line would have left, because a ceiling that fails on the next honest byte is a gate proving nothing. 18.5 -> 19 KB for the FLAT TILE and the block rhythm (owner's walk of the storefront, dark theme). Measured with dependencies held constant, this package's src at the commit before this wave and then at it: 18209 -> 18652 B — 443 B, raised here rather than left as a red somebody reruns. Two thirds of it is `<CategoryTileGrid tileSurface>`: the `\"flat\"` default (no fill and no border at rest, the same token fill and radius arriving on `:hover` / `:focus-visible`) is a hoisted rule set plus a class per tile plus the `tileStyle` arm that drops the inline `background` — an inline fill would beat the sheet's own hover rule, so it has to LEAVE rather than be overwritten — plus `className` on `<CategoryLink>` (already in core's `LinkComponentProps`, so no shared type moved) and `<CategoryPage subcategoryTileSurface>`. A dozen filled boxes on a landing outweigh the art inside them, which is what the fill was costing. The rest is `blockRhythm.ts`: one gap for every block from `var(--stapel-block-gap)` / `var(--stapel-block-gap-compact)` with each block's outer margin reset, replacing the flat `spacing[4]` three `<Flex>`es wrote inline — the same two property names `@stapel/search-react` declares, so a storefront tunes both halves of a category screen with one declaration. 19 KB leaves 348 B, the same order of room the 17.8 -> 18.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing. 19 KB HOLDS for the flat tile's own ANATOMY and the row-accurate stage (owner's read of the stand at 0.27.0, both themes): measured 18797 B against the 19 KB line, 145 B over the 18652 B this note last recorded, and 203 B of room left. Taking the fill away was half the change — the card anatomy puts the caption top-left and the art bottom-right, and the box was what held those two marks together, so six flat tiles across a desktop row read as a loose list. `tileFlat`/`labelFlat`/`isFlatStack` give the flat tile the dense phone grid's arrangement instead (art over caption, both centred) at the card's own type size, ratio and padding — the arrangement moves and the BOX does not, so every reservation and track height is untouched. The rest is `tileStageRows(count, columns)` and `<CategoryTileGrid reserveCount>`: the reservation is one skeleton per tile in the grid the tiles land in rather than a fixed four, and the scroller stops declaring a second row it has no tile for — an empty band and its gap under the only thing on screen. The rule is exported because a host holding the stage's box from outside this pair had nothing to ask and was guessing a height, which is the defect this note keeps recording under other names. A budget is not raised for a change that fits under the line it already has. 19 KB HOLDS for the COMPACT flat tile too (architect's verdict, superseding the 2026-09-04 ruling for the flat surface only): measured 18846 B against the 19 KB line, 49 B over the 18797 B this note last recorded, and 154 B of room left — the next change to this entry spends them. `size: \"compact\"` is a horizontal row half a tile high, and the 2026-09-04 anatomy put the name at one end of it and the picture at the other: a CARD's arrangement for exactly the reason the regular tile's corners were, since the fill is what makes two marks at opposite ends read as one thing. Without it the row is scattered text with a gap in the middle (measured on the stand), so the flat compact tile is a LIST ROW — art first, caption second, adjacent, against the leading edge. The 49 B is `tileSizeCompactFlat` (one overridden property), `isFlatRow` beside `isFlatStack`, and `tileBody`'s compact early return becoming the CARD's. Height, density and padding are the 2026-09-04 ruling either way, and `size: \"compact\"` + `tileSurface: \"card\"` is that ruling untouched. 19 KB HOLDS for the CONTAINER's surface (owner's read of 0.29.0, dark): measured 18864 B against the 19 KB line, 18 B over the 18846 B this note last recorded, and 136 B of room left — the next change to this entry spends them and then some. The tiles went flat and the box around them did not: `SkinTheme` defaults to `surface=\"raised\"`, so the whole component still painted `colorBgContainer` — a lighter strip the width of the grid on the desktop catalogue page, a full panel on the phone and behind the landing's compact strip. The same block fill the tiles had just lost, one box further out, and invisible to every rule in this file because the wrapper paints it: the wrap grid, the scroller and the reserve box all sit inside it and paint nothing of their own, which is why one gate is all three. The 18 B is that gate plus the flat arm's `color: var(--stapel-text)` — `bare` paints nothing, including the text colour `raised` would have written, and stating the custom property instead is strictly better than the frozen value it replaces. `\"card\"` keeps the panel. 19 -> 19.5 KB for the STRIP taking the same surface (this wave): measured 18967 B, 103 B over the 18864 B this note last recorded. It FITS under the 19 KB line — and the line is then left with 33 B, which by this entry's own standard is not a ceiling but a gate that fails on the next honest byte, so it is raised here rather than left as a red for the wave after this one. `<CategoryCarouselStrip tileSurface>` is the same word, the same default and the same rule as the grid's: `bare` plus `color: var(--stapel-text)` on the wrapper, and — flat — no antd `Card` behind an entry at all, the LINK carrying the tile's box and the two classes instead, so the whole tile is the target and its hover fill comes from `categoryTileCss()` itself. That is where most of the 103 B went and why it is not more: the hover is `<CategoryTileGrid>`'s published rule set, hoisted under the same `href`, so a landing drawing both rows ships one copy and there is no second definition to drift from the first. A landing that is flat in one row and panelled in the next is worse than either. 19.5 KB leaves 533 B. 19.5 KB HOLDS for the TRAIL taking the same surface: measured 18967 B, byte-for-byte the number this note last recorded — `<CategoryBreadcrumbsBar>` swaps `SkinTheme`'s default `raised` for `bare` plus the same `color: var(--stapel-text)` the grid and the strip already state, and one prop for another costs nothing after brotli. It is the third and last component in this package that painted `colorBgContainer` behind flat content: a 1392x24 ribbon over every category and listing page, measured dark on a live storefront. A budget is not raised for a change that fits under the line it already has. 19.5 -> 20 KB for the mega-menu becoming an OVERLAY in its own right (owner's desktop read of the stand, 2026-09-14). Measured with dependencies held constant, this package's src at HEAD before this wave and then at it: 19154 -> 19530 B — 376 B, and the line was already 187 B past the 18967 B this note last recorded (the card tile's tint and the trail's surface landed under it without a note), so the 346 B of room the last raise left had become 30 B of red. The 376 B is three things the panel now owns instead of the host: its own scroll box (`maxHeight`, `overflow-y: auto`, `overscroll-behavior: contain` — measured on the stand, the host's wrapper had nothing to scroll and the wheel chained 1500px into the page); the page lock while mounted (`lockPageScroll`, reference-counted, `scrollbar-gutter: stable` beside the hidden overflow, the same lock `SkinDialog` keeps private); and the rail row's fill leaving the style attribute for a hoisted sheet (`megaMenuCss`, the root class and its `-active` modifier) so `:hover` and `:focus-visible` can be said at all — plus `railWidth` and the trailing chevron. 20 KB leaves 470 B, the same order of room the 19 -> 19.5 raise left, because a ceiling that fails on the next honest byte is a gate proving nothing.","path":"dist/default/index.js","limit":"20 KB"},{"name":"i18n/ru — the Russian bundle is opt-in, not carried by the main entry","path":"dist/i18n/ru.js","limit":"4 KB"},{"name":"i18n/es — the Spanish bundle is opt-in, not carried by the main entry","path":"dist/i18n/es.js","limit":"3.5 KB"}],"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","directories":{},"maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"antd":"^6.5.0","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","size-limit":"^11.2.0","typescript":"^5.8.3","@stapel/core":"^0.28.0","@types/react":"^19.1.0","@stapel/tokens":"^0.8.1","@stapel/showcase":"^0.3.0","@types/react-dom":"^19.1.0","@stapel/tokens-antd":"^0.22.1","@tanstack/react-query":"^5.81.0","@testing-library/react":"^16.3.0","@stapel/attributes-react":"^0.17.1","@size-limit/preset-small-lib":"^11.2.0"},"peerDependencies":{"antd":">=5.20.0 <7","react":">=19","@stapel/core":">=0.26.0 <1.0.0","@stapel/tokens-antd":">=0.11.0","@tanstack/react-query":"^5.0.0","@stapel/attributes-react":">=0.16.6"},"peerDependenciesMeta":{"antd":{"optional":true},"@stapel/tokens-antd":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/categories-react_0.35.0_1790376396960_0.7317279001480286"}}},"time":{"created":"2026-08-22T13:06:42.188Z","modified":"2026-09-25T22:46:37.427Z","0.1.0":"2026-08-22T13:06:42.517Z","0.2.0":"2026-08-22T23:50:58.609Z","0.3.0":"2026-08-23T08:03:37.830Z","0.3.1":"2026-08-23T17:35:00.089Z","0.5.0":"2026-08-26T20:58:57.710Z","0.5.1":"2026-08-30T21:08:10.094Z","0.6.0":"2026-08-31T01:17:48.402Z","0.7.0":"2026-08-31T09:53:02.730Z","0.8.0":"2026-09-01T19:44:10.288Z","0.9.1":"2026-09-01T21:32:41.201Z","0.10.0":"2026-09-02T05:58:59.554Z","0.10.1":"2026-09-02T09:21:24.992Z","0.12.0":"2026-09-02T15:56:56.637Z","0.12.1":"2026-09-03T00:53:35.968Z","0.13.0":"2026-09-03T03:54:48.264Z","0.14.0":"2026-09-03T04:25:54.631Z","0.15.0":"2026-09-04T06:34:52.828Z","0.16.0":"2026-09-04T07:35:32.387Z","0.17.0":"2026-09-04T10:12:27.291Z","0.18.0":"2026-09-04T12:01:09.213Z","0.19.0":"2026-09-04T14:07:28.493Z","0.20.0":"2026-09-04T16:43:33.871Z","0.22.0":"2026-09-04T22:46:32.769Z","0.22.1":"2026-09-05T14:20:56.972Z","0.22.2":"2026-09-05T22:10:04.388Z","0.22.3":"2026-09-06T01:59:05.961Z","0.23.0":"2026-09-06T11:00:54.776Z","0.24.0":"2026-09-06T14:16:01.821Z","0.24.1":"2026-09-06T15:47:34.479Z","0.24.2":"2026-09-06T19:29:39.916Z","0.25.0":"2026-09-08T09:08:52.114Z","0.25.1":"2026-09-08T10:12:32.222Z","0.26.0":"2026-09-10T00:53:10.469Z","0.27.0":"2026-09-10T10:33:27.771Z","0.28.0":"2026-09-10T12:22:31.629Z","0.29.0":"2026-09-10T13:57:58.557Z","0.30.0":"2026-09-10T14:59:04.139Z","0.31.0":"2026-09-11T01:39:26.485Z","0.31.1":"2026-09-12T00:55:05.961Z","0.31.2":"2026-09-13T04:00:31.693Z","0.31.3":"2026-09-13T05:19:21.209Z","0.31.4":"2026-09-13T11:59:03.228Z","0.32.0":"2026-09-14T18:38:24.006Z","0.33.0":"2026-09-16T00:13:54.907Z","0.33.1":"2026-09-18T02:09:36.548Z","0.34.0":"2026-09-18T06:13:09.501Z","0.35.0":"2026-09-25T22:46:37.082Z"},"license":"MIT","repository":{"url":"https://github.com/usestapel/stapel-react.git","type":"git","directory":"packages/categories-react"},"description":"Headless React pair for stapel-categories: a typed client, a client-assembled category tree, and the revision-delta sync the module documents. The list endpoint returns FLAT rows with treenode ancestry as comma-joined pk strings — this package parses them","maintainers":[{"name":"ucsoftworks","email":"ucsoftworks@gmail.com"}],"readme":"","readmeFilename":""}